package com.imdroid.lite.process;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.baidu.mapapi.GeoPoint;
import com.imdroid.lite.IMDroid;
import com.imdroid.lite.R;
import com.imdroid.lite.activities.CarLocationActivity;
import com.imdroid.lite.model.Destination;
import com.imdroid.lite.model.User;
import com.imdroid.lite.net.HttpHelper;

public class UserProcess extends BaseProcess {
	/**
	 * The tag
	 */
	private static final String TAG = "UserProcess";

	/**
	 * Get the user according the device IMET, the return string format is
	 * below:
	 * 
	 * [0] - "IM" - the succesfull tag [1] - 用户 Id [2] - 车机-imei [3] -
	 * 车机-sim卡号�? [4] - 用户名称 [5] - 用户手机号码 [6] - 车型 [7] - 车牌号码 [8] - 车架号码 [9] -
	 * 发动机号 [10] 昵称 [11] 购买日期 [12] 微博账号 [13] 微博令牌 [14] 微信账号 [15] 微信令牌 [16] 性别
	 * 
	 * @param userName
	 *            the user name of user
	 * @param passWord
	 *            the password of user
	 * @param type
	 *            the type of user
	 * @return the target user.
	 * @throws Exceptiom
	 */
	@SuppressLint("SimpleDateFormat")
	public User getUser(String userName, String passWord) throws Exception {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("userName", userName));
		params.add(new BasicNameValuePair("passWord", passWord));

		String url = "GetLiteUserInfo";
		String response = HttpHelper.execute(url, params);

		// 返回字串是否正确
		if (!response.trim().startsWith("IM"))
			throw new Exception(IMDroid.getAppContext().getString(
					R.string.error_http_invalid_header));

		// 组成User对象
		User user = new User();
		String[] item = split(response, "%%");
		user.setUser_id(Integer.valueOf(item[1]));
		user.setUser_name(item[4]);
		user.setPassword(passWord);
		user.setMobile_phone(item[5]);
		user.setVechile_model(item[6]);
		user.setBoard_plate(item[7]);
		user.setNickname(item[10]);
		user.setType(Integer.parseInt(item[17]));
		user.setParentId(item[18] != null && item[18].trim().length() > 0 ? Integer
				.parseInt(item[18]) : 0);
		user.setTeam_access_code(item[19]);
		if (user.getParentId() > 0)
			user.setParentName(getParentName(user.getParentId()));
		return user;
	}

	/**
	 * Post the user change to server
	 * 
	 * @param target
	 *            the target new user
	 * @param validate_code
	 *            the code of validate
	 * @throws Exception
	 */
	public User registerVistor(User target, String validate_code)
			throws Exception {
		TelephonyManager tm = (TelephonyManager) IMDroid.getAppContext()
				.getSystemService(Context.TELEPHONY_SERVICE);
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("user_name", target.getUser_name()));
		params.add(new BasicNameValuePair("mobile_phone", target
				.getMobile_phone()));
		params.add(new BasicNameValuePair("vechile_model", target
				.getVechile_model()));
		params.add(new BasicNameValuePair("board_plate", target
				.getBoard_plate()));
		params.add(new BasicNameValuePair("nickname", target.getNickname()));
		params.add(new BasicNameValuePair("password", target.getPassword()));
		params.add(new BasicNameValuePair("access_code", target
				.getTeam_access_code()));
		params.add(new BasicNameValuePair("registerCode", validate_code));
		params.add(new BasicNameValuePair("imei", tm.getDeviceId()));
		String response = HttpHelper.execute("RegisterVistor", params).trim();
		// 返回字串是否正确
		if (!response.trim().startsWith("IM"))
			throw new Exception(IMDroid.getAppContext().getString(
					R.string.error_http_invalid_header));

		// 组成User对象
		User user = new User();
		String[] item = split(response, "%%");
		user.setUser_id(Integer.valueOf(item[1]));
		user.setUser_name(item[4]);
		user.setMobile_phone(item[5]);
		user.setVechile_model(item[6]);
		user.setBoard_plate(item[7]);
		user.setNickname(item[10]);
		user.setType(Integer.parseInt(item[17]));
		user.setParentId(item[18] != null && item[18].trim().length() > 0 ? Integer
				.parseInt(item[18]) : 0);
		user.setTeam_access_code(item[19]);
		if (user.getParentId() > 0)
			user.setParentName(getParentName(user.getParentId()));		
		return user;
	}

	/**
	 * Update the user in user
	 * 
	 * @param target
	 *            update the user
	 * @return if it is success.
	 * @throws Exception
	 */
	public boolean udateUser(User target) throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("user_id", target.getUser_id() + ""));
		params.add(new BasicNameValuePair("user_name", target.getUser_name()));
		params.add(new BasicNameValuePair("mobile_phone", target
				.getMobile_phone()));
		params.add(new BasicNameValuePair("vechile_model", target
				.getVechile_model()));
		params.add(new BasicNameValuePair("board_plate", target
				.getBoard_plate()));
		params.add(new BasicNameValuePair("nickname", target.getNickname()));
		params.add(new BasicNameValuePair("password", target.getPassword()));
		params.add(new BasicNameValuePair("access_code", target
				.getTeam_access_code()));

		boolean success = "1".equals(HttpHelper.execute("UpdateVistorOrLite",
				params).trim());
		if (success) {
			IMDroid.registerUser(target);
		}
		return success;
	}

	/**
	 * Get the device location of user
	 * 
	 * @param user
	 *            the user
	 * @return the location of the device
	 * @throws Exception
	 */
	public CarLocationActivity.LocationAndTime getDeviceLocation(User user)
			throws Exception {
		final List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("deviceId", user.getParentId() + ""));
		String result = HttpHelper.execute("GetUserLocation3", params);

		String[] items = result.split("%%");
		double lon = Double.parseDouble(items[1]);
		double lat = Double.parseDouble(items[2]);
		long time = Long.parseLong(items[3]);
		if (lon == 0 && lat == 0)
			throw new Exception(IMDroid.getAppContext().getString(
					R.string.car_exception));
		Date date = new Date(time);
		return new CarLocationActivity.LocationAndTime(new GeoPoint(
				(int) (lon * 1E6), (int) (lat * 1E6)), time > 0 ? date : null);

	}

	/**
	 * @param deviceId
	 *            the device of the
	 * @param days
	 * @return
	 * @throws Exception
	 */
	public Map<String, List<GeoPoint>> getCarLocation(int days)
			throws Exception {
		String strStartTime = "";
		int intLat = 0;
		int intLot = 0;
		GeoPoint geoPoint;
		Map<String, List<GeoPoint>> rtnPathsMap = new HashMap<String, List<GeoPoint>>();

		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("deviceId", IMDroid.getUser()
				.getParentId() + ""));
		params.add(new BasicNameValuePair("day", days + ""));
		String strRtn = HttpHelper.execute("GetUserPath", params).trim();
		if (strRtn == null) {
			return null;
		} else if (strRtn.indexOf("EX") > 0) {
			return null;
		} else if (strRtn.indexOf("[") == 0) {
			strRtn = "{'paths':" + strRtn + "}";
		}

		JSONArray jsonArray = new JSONObject(strRtn).getJSONArray("paths");

		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject jsonObject = (JSONObject) jsonArray.opt(i);

			strStartTime = jsonObject.getString("start_time");
			intLat = (int) (jsonObject.getDouble("pos_lat") * 1E6);
			intLot = (int) (jsonObject.getDouble("pos_lon") * 1E6);
			if (intLat == 0 || intLot == 0)
				continue;
			geoPoint = new GeoPoint(intLat, intLot);

			if (rtnPathsMap.containsKey(strStartTime)) {
				rtnPathsMap.get(strStartTime).add(geoPoint);
			} else {
				List<GeoPoint> lstTemp = new ArrayList<GeoPoint>();
				lstTemp.add(geoPoint);
				rtnPathsMap.put(strStartTime, lstTemp);
			}
		}
		return rtnPathsMap;
	}

	/**
	 * Send the destination
	 * 
	 * @param destination
	 *            the destination to be send
	 * @return if successful
	 * @throws Exception
	 */
	public boolean sendDestination(Destination destination, Context context)
			throws Exception {
		if (destination == null)
			return false;

		// 查找车机
		User parent = getParentDevice();
		if (parent == null)
			throw new Exception(IMDroid.getAppContext().getString(
					R.string.car_no_found));
		// 发送短信
		PendingIntent intent = PendingIntent.getBroadcast(context, 0,
				new Intent(), 0);
		SmsManager sms = SmsManager.getDefault();
		sms.sendTextMessage(parent.getSim_number(), null,
				formatDestinationMessage(destination), intent, null);// 发送信息到指定号码

		return true;
	}

	/**
	 * The sms message need to formation
	 * 
	 * @param destination
	 *            destination
	 * @return the sms message need to formation
	 * @throws Exception
	 */
	private String formatDestinationMessage(Destination destination)
			throws Exception {

		return "IMD##109&&"
				+ ((destination.getName() != null) ? destination.getAddress()
						.trim() : "") + "&&" + destination.getLatitude() + "&&"
				+ destination.getLongitude();

	}

	/**
	 * Request the device to take the picture
	 * 
	 * @return if successful
	 * @throws Exception
	 */
	public String takePicture(Context context) throws Exception {
		// 查找车机
		User parent = getParentDevice();
		if (parent == null)
			throw new Exception(IMDroid.getAppContext().getString(
					R.string.car_no_found));
		// 决定回复电话号码
		TelephonyManager tm = (TelephonyManager) IMDroid.getAppContext()
				.getSystemService(Context.TELEPHONY_SERVICE);
		String tel = (tm.getLine1Number() != null && tm.getLine1Number().trim()
				.length() > 0) ? tm.getLine1Number().trim() : parent
				.getMobile_phone();
		// 发送短信
		PendingIntent intent = PendingIntent.getBroadcast(context, 0,
				new Intent(), 0);
		SmsManager sms = SmsManager.getDefault();
		sms.sendTextMessage(parent.getSim_number(), null,
				formatTakingPictureMessage(tel), intent, null);// 发送信息到指定号码
		Log.d(TAG, "Mobile--" + parent.getSim_number());
		Log.d(TAG, "Mobile--" + formatTakingPictureMessage(tel));
		return tel;
	}

	/**
	 * Format the message of taking picture
	 * 
	 * @return the sms string after format.
	 */
	public String formatTakingPictureMessage(String feedBackNumber) {
		return "IMD##120&&" + feedBackNumber;
	}

	/**
	 * Get the information of the parent device
	 * 
	 * @return the parent device
	 * @throws Exception
	 */
	private User getParentDevice() throws Exception {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("userId", IMDroid.getUser()
				.getParentId() + ""));

		String url = "GetUserInfoById";
		String response = HttpHelper.execute(url, params);

		// 返回字串是否正确
		if (!response.trim().startsWith("IM"))
			throw new Exception(IMDroid.getAppContext().getString(
					R.string.error_http_invalid_header));

		// 组成User对象
		User parent = new User();
		String[] item = split(response, "%%");
		parent.setUser_id(Integer.valueOf(item[1]));
		parent.setSim_number(item[3]);
		parent.setUser_name(item[4]);
		parent.setMobile_phone(item[5]);
		parent.setVechile_model(item[6]);
		parent.setBoard_plate(item[7]);
		parent.setNickname(item[10]);
		parent.setType(Integer.parseInt(item[17]));
		parent.setParentId(item[18] != null && item[18].trim().length() > 0 ? Integer
				.parseInt(item[18]) : 0);
		parent.setTeam_access_code(item[19]);
		return parent;

	}

	/**
	 * Get the last version number from the server
	 * 
	 * @return The last version from the server
	 * @throws Exception
	 */
	public String getLastVersion() throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("type", "L"));
		return HttpHelper.execute("CheckVersion", params).trim();
	}

	/**
	 * synchronize the contract to server
	 * 
	 * @param context
	 *            the application context
	 * @throws Exception
	 */
	public void synchronizeContact(Context context) throws Exception {
		// 提取电话的联系人信息
		Map<String, String> contract = getContract(context);
		// 上传至服务器
		for (String phoneNumber : contract.keySet()) {
			String displayName = contract.get(phoneNumber);
			Log.d(TAG, displayName + " - " + phoneNumber);
			uploadContact(phoneNumber, displayName);
		}
	}

	/**
	 * Get all the contracts in the phone
	 * 
	 * @param context
	 *            the application context
	 * @return all the contracts
	 */
	private Map<String, String> getContract(Context context) {
		Map<String, String> map = new HashMap<String, String>();
		// 获取联系人
		Cursor cusror = context.getContentResolver().query(
				ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

		if (!cusror.moveToFirst())
			return map;

		int idColumn = cusror.getColumnIndex(ContactsContract.Contacts._ID);
		int displayNameColumn = cusror
				.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);

		// 循环遍历所有联系人
		do {
			// 获得联系人的ID号及姓名
			String contactId = cusror.getString(idColumn);
			String disPlayName = cusror.getString(displayNameColumn);
			Log.d(TAG, "sync contac2t:" + contactId + " " + disPlayName);

			int phoneCount = cusror
					.getInt(cusror
							.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
			if (phoneCount > 0) {
				// 获得联系人的电话号码
				Cursor phones = context.getContentResolver().query(
						ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
						null,
						ContactsContract.CommonDataKinds.Phone.CONTACT_ID
								+ " = " + contactId, null, null);
				// 遍历所有的电话号码
				if (phones.moveToFirst()) {
					do {
						String phoneNumber = phones
								.getString(phones
										.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
						// 以电话号码为关键字
						map.put(phoneNumber, disPlayName);
					} while (phones.moveToNext());
				}
				phones.close();
				// break;
			}
		} while (cusror.moveToNext());
		cusror.close();
		return map;
	}

	/**
	 * Upload to server
	 * 
	 * @return successful or not
	 * @throws Exception
	 */
	private boolean uploadContact(String phoneNumber, String displayName)
			throws Exception {
		User user = IMDroid.getUser();
		JSONObject contact = new JSONObject();
		contact.put("phoneNumber", phoneNumber);
		contact.put("displayName", displayName);
		contact.put("parent_id", user.getParentId());

		Log.d(TAG, "sync contact json:" + contact.toString());

		String response = HttpHelper.execute("SyncContractSet", "contact",
				contact);
		return "1".equals(response);
	}

	/**
	 * Get a new register code
	 * 
	 * @param phoneNumber
	 *            the phone number
	 * @return a new register code
	 * @throws Exception
	 */
	public String getNewRegisterCode(String phoneNumber) throws Exception {
		TelephonyManager tm = (TelephonyManager) IMDroid.getAppContext()
				.getSystemService(Context.TELEPHONY_SERVICE);
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("phoneNumber", phoneNumber));
		params.add(new BasicNameValuePair("imei", tm.getDeviceId()));

		String response = HttpHelper.execute("RegisterCodeNew", params);
		if (response != null && response.trim().length() > 0)
			return response.trim();
		else
			throw new Exception("Unable to get the validation");
	}

	/**
	 * Get the close match device
	 * 
	 * @param current_lat
	 *            the latitude
	 * @param current_lon
	 *            the longtiude
	 * @return the userid and the nick name
	 * @throws Exception
	 */
	public String getCloseMatchDevice(double current_lat, double current_lon)
			throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("current_lat", current_lat + ""));
		params.add(new BasicNameValuePair("current_lon", current_lon + ""));

		return HttpHelper.execute("MatchCodeFind", params);

	}

	/**
	 * Get the close match device
	 * 
	 * @param device_id
	 *            the latitude
	 * @param lite_id
	 *            the longtiude
	 * @param matchCode
	 *            the match Code
	 * @return the user id and the nick name
	 * @throws Exception
	 */
	public boolean matchDevice(int device_id, int lite_id, String matchCode)
			throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("device_user_id", device_id + ""));
		params.add(new BasicNameValuePair("lite_user_id", lite_id + ""));
		params.add(new BasicNameValuePair("matchCode", matchCode + ""));

		boolean s = HttpHelper.execute("MatchByCode", params).trim()
				.equals("1");
		if (s) {
			IMDroid.getUser().setType(User.TYPE_DEVICE_LITE);
			IMDroid.getUser().setParentId(device_id);
			IMDroid.getUser().setParentName(getParentName(device_id));
			IMDroid.registerUser(IMDroid.getUser());
		}
		return s;
	}

	/**
	 * Get the nick name of the parent device
	 * 
	 * @param parent_id
	 *            the id of the parent
	 * @return the nick name of parent device
	 * @throws Exception
	 */
	public String getParentName(int parent_id) throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("userId", parent_id + ""));
		String s = HttpHelper.execute("GetUserInfoById", params).trim();
		if (s == null || s.length() <= 0)
			return "";
		String[] items = s.split("%%");
		return items[10];

	}
}
